﻿using LF.Shared.Dtos.Out;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using WeixinSDK.Work;
using WeixinSDK.Work.Models.Message;
using System.Security.Cryptography;
using System.Text.Json;
using LF.Domain.Services;
using Microsoft.AspNetCore.Http;

namespace LF.Application.Helpers
{
    public class QyWeixinHelper
    {
        static string BaseUrl => "https://qyapi.weixin.qq.com";


        /// <summary>
        /// 获取企业微信accesstoken
        /// </summary>
        /// <returns></returns>
        public static async Task<string> GetAccessToken()
        {
            try
            {
                var config = LFConfig.QyWeixin;
                Console.WriteLine($"QyWeixin GetAccessToken - 开始获取Token");
                Console.WriteLine($"QyWeixin GetAccessToken - CorpId: {config.WeixinCorpId}, Secret: {config.WeixinCorpSecret?.Substring(0, Math.Min(10, config.WeixinCorpSecret.Length))}...");
                
                Console.WriteLine($"QyWeixin GetAccessToken - 准备调用API: {BaseUrl}/cgi-bin/gettoken");
                var result = await ApiHelper.GetAsync(BaseUrl, "cgi-bin/gettoken", new Dictionary<string, object> {
                    { "corpid",config.WeixinCorpId},
                    { "corpsecret",config.WeixinCorpSecret}
                });
                Console.WriteLine($"QyWeixin GetAccessToken - API调用完成");
                
                Console.WriteLine($"QyWeixin GetAccessToken - API Response: {System.Text.Json.JsonSerializer.Serialize(result)}");
                
                if (result != null)
                {
                    var errcode = result["errcode"]?.GetValue<int>() ?? 0;
                    var errmsg = result["errmsg"]?.GetValue<string>() ?? "";
                    
                    if (errcode != 0)
                    {
                        Console.WriteLine($"QyWeixin GetAccessToken - 获取token失败: {errcode} - {errmsg}");
                    }
                    
                    var accessToken = result["access_token"]?.GetValue<string>();
                    //Console.WriteLine($"QyWeixin GetAccessToken - Token: {accessToken?.Substring(0, Math.Min(20, accessToken.Length ?? 0))}...");
                    return accessToken ?? "";
                }
                else
                {
                    Console.WriteLine($"QyWeixin GetAccessToken - API返回结果为null");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"QyWeixin GetAccessToken - 异常: {ex.Message}");
                Console.WriteLine($"QyWeixin GetAccessToken - 异常堆栈: {ex.StackTrace}");
            }
            return "";
        }
        /// <summary>
        /// 发送小程序消息
        /// </summary>
        /// <returns></returns>
        public static async Task<string> SendMiniMessage(string usercode, string title, string? description, string? page = "pages/index/index")
        {
            var token = await GetAccessToken();
            var config = LFConfig.QyWeixin;
            var result = await ApiHelper.PostAsync(BaseUrl, $"cgi-bin/message/send?access_token={token}", new Dictionary<string, object> {
                { "touser",usercode},
                { "msgtype","miniprogram_notice"},
                { "miniprogram_notice",new {appid= config.AppId, page= page,
        title= title,
        description= description,
        emphasis_first_item= true } }
            });
            var accessToken = result!["errmsg"]?.GetValue<string>();
            return accessToken ?? "";
        }

        /// <summary>
        /// 发送企业微信消息
        /// </summary>
        /// <param name="eventData">消息事件数据</param>
        /// <returns>发送结果</returns>
        public static bool SendQyWeixinMessage(PlanMsgEventData eventData)
        {
            try
            {
                var config = LFConfig.QyWeixin;
                if (string.IsNullOrEmpty(config.WeixinCorpId) || string.IsNullOrEmpty(config.WeixinCorpSecret))
                {
                    Console.WriteLine("企业微信配置信息不完整");
                    return false;
                }

                var client = new WeixinWorkApiClient(config.WeixinCorpId, Convert.ToInt32(config.WeixinCorpAgentId), config.WeixinCorpSecret);
                
                if (string.IsNullOrEmpty(eventData.url))
                {
                    // 发送文本消息
                    var result = client.Message.SendText(
                        new SendTextRequest()
                        {
                            UserIds = eventData.users,
                            text = new TextMessageInfo()
                            {
                                content = eventData.title
                            }
                        }
                    );
                    Console.WriteLine($"发送文本消息完成");
                    return true;
                }
                else
                {
                    // 发送文本卡片消息
                    var processedUrl = (eventData.url ?? "")
                        .Replace("workwxappurl", LFConfig.WorkWxApp ?? "")
                        .Replace("/#", $"?rad={Guid.NewGuid()}/#");
                    
                    var result = client.Message.SendTextCard(
                        new SendTextCardRequest()
                        {
                            UserIds = eventData.users,
                            textcard = new TextCardMessageInfo()
                            {
                                url = processedUrl,
                                title = eventData.title,
                                description = eventData.description
                            }
                        }
                    );
                    Console.WriteLine($"发送文本卡片消息完成");
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送企业微信消息失败: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                return false;
            }
        }

        /// <summary>
        /// 通过授权码获取用户信息
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>用户信息</returns>
        public static async Task<QyWeixinUserInfo?> GetUserInfoByCodeAsync(string code)
        {
            var token = await GetAccessToken();
            var result = await ApiHelper.GetAsync(BaseUrl, "cgi-bin/user/getuserinfo", new Dictionary<string, object> {
                { "access_token", token},
                { "code", code}
            });
            Console.WriteLine(code);
            Console.WriteLine($"QyWeixin GetUserInfoByCode - API Response: {System.Text.Json.JsonSerializer.Serialize(result)}");
            if (result != null && !string.IsNullOrEmpty(result!["UserId"]?.GetValue<string>()))
            {
                return new QyWeixinUserInfo
                {
                    UserId = result["UserId"]?.GetValue<string>() ?? "",
                    DeviceId = result["DeviceId"]?.GetValue<string>(),
                    OpenId = result["user_ticket"]?.GetValue<string>(),
                    ExternalUserId = result["external_userid"]?.GetValue<string>()
                };
            }
           

            return null;
        }

        /// <summary>
        /// 通过企业微信用户详细信息
        /// </summary>
        /// <param name="userinfo">企业微信用户信息</param>
        /// <returns>用户详细信息</returns>
        public static async Task<QyWeixinUserDetail?> GetUserDetailAsync(QyWeixinUserInfo userinfo)
        {
            try
            {

                var token = await GetAccessToken();
              
                Console.WriteLine($"QyWeixin GetUserDetail - 准备调用用户详情API: {BaseUrl}/cgi-bin/user/get");
                var result = await ApiHelper.GetAsync(BaseUrl, "cgi-bin/user/get", new Dictionary<string, object> {
                    { "access_token", token},
                    { "userid", userinfo.UserId}
                });
                var result2 = await ApiHelper.PostAsync(BaseUrl, $"cgi-bin/auth/getuserdetail?access_token={token}", new Dictionary<string, object> {
                { "user_ticket", userinfo.OpenId},

            });
                Console.WriteLine($"QyWeixin GetUserDetail - 用户详情API调用完成");

                Console.WriteLine($"QyWeixin GetUserDetail - API Response: {System.Text.Json.JsonSerializer.Serialize(result)}");

                if (result != null&&result2!=null)
                {
                    var errcode = result["errcode"]?.GetValue<int>() ?? -1;
                    var errmsg = result["errmsg"]?.GetValue<string>() ?? "";
                    
                    Console.WriteLine($"QyWeixin GetUserDetail - ErrCode: {errcode}, ErrMsg: {errmsg}");
                    
                    if (errcode == 0)
                    {
                        return new QyWeixinUserDetail
                        {
                            UserId = result["userid"]?.GetValue<string>() ?? "",
                            Name = result["name"]?.GetValue<string>() ?? "",
                            Mobile = result2["mobile"]?.GetValue<string>() ?? "",
                            Email = result2["email"]?.GetValue<string>() ?? "",
                            Avatar = result2["avatar"]?.GetValue<string>() ?? "",
                            Gender = result2["gender"]?.GetValue<string>() ?? ""
                        };
                    }
                    else
                    {
                        Console.WriteLine($"QyWeixin GetUserDetail - 企业微信API返回错误: {errcode} - {errmsg}");
                    }
                }
                else
                {
                    Console.WriteLine($"QyWeixin GetUserDetail - API返回结果为null");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"QyWeixin GetUserDetail - 异常: {ex.Message}");
                Console.WriteLine($"QyWeixin GetUserDetail - 异常堆栈: {ex.StackTrace}");
            }
            return null;
        }

        /// <summary>
        /// 获取JSAPI ticket
        /// </summary>
        /// <returns>JSAPI ticket</returns>
        public static async Task<string> GetJsApiTicketAsync()
        {
            try
            {
                var token = await GetAccessToken();
                if (string.IsNullOrEmpty(token))
                {
                    Console.WriteLine("QyWeixin GetJsApiTicket - AccessToken为空");
                    return "";
                }

                Console.WriteLine($"QyWeixin GetJsApiTicket - 准备调用JSAPI ticket API: {BaseUrl}/cgi-bin/get_jsapi_ticket");
                var result = await ApiHelper.GetAsync(BaseUrl, "cgi-bin/get_jsapi_ticket", new Dictionary<string, object> {
                    { "access_token", token},
                    { "type", "jsapi"}
                });
                Console.WriteLine($"QyWeixin GetJsApiTicket - API调用完成");

                Console.WriteLine($"QyWeixin GetJsApiTicket - API Response: {System.Text.Json.JsonSerializer.Serialize(result)}");

                if (result != null)
                {
                    var errcode = result["errcode"]?.GetValue<int>() ?? -1;
                    var errmsg = result["errmsg"]?.GetValue<string>() ?? "";
                    
                    if (errcode == 0)
                    {
                    var ticket = result["ticket"]?.GetValue<string>();
                    Console.WriteLine($"QyWeixin GetJsApiTicket - 获取ticket成功: {(ticket != null ? ticket.Substring(0, Math.Min(20, ticket.Length)) : "null")}...");
                        return ticket ?? "";
                    }
                    else
                    {
                        Console.WriteLine($"QyWeixin GetJsApiTicket - 获取ticket失败: {errcode} - {errmsg}");
                    }
                }
                else
                {
                    Console.WriteLine($"QyWeixin GetJsApiTicket - API返回结果为null");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"QyWeixin GetJsApiTicket - 异常: {ex.Message}");
                Console.WriteLine($"QyWeixin GetJsApiTicket - 异常堆栈: {ex.StackTrace}");
            }
            return "";
        }

        /// <summary>
        /// 生成JSAPI签名
        /// </summary>
        /// <param name="url">当前页面URL</param>
        /// <returns>签名配置信息</returns>
        public static async Task<JsApiSignatureConfig?> GenerateJsApiSignatureAsync(string url)
        {
            try
            {
                var ticket = await GetJsApiTicketAsync();
                if (string.IsNullOrEmpty(ticket))
                {
                    Console.WriteLine("QyWeixin GenerateJsApiSignature - Ticket为空");
                    return null;
                }

                var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                var nonceStr = Guid.NewGuid().ToString("N")[..16];

                // 生成签名
                var signature = GenerateSignature(ticket, timestamp.ToString(), nonceStr, url);

                return new JsApiSignatureConfig
                {
                    Timestamp = timestamp,
                    NonceStr = nonceStr,
                    Signature = signature,
                    CorpId = LFConfig.QyWeixin.WeixinCorpId
                };
            }
            catch (Exception ex)
            {
                Console.WriteLine($"QyWeixin GenerateJsApiSignature - 异常: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 生成签名
        /// </summary>
        /// <param name="ticket">jsapi ticket</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonceStr">随机字符串</param>
        /// <param name="url">URL</param>
        /// <returns>签名</returns>
        private static string GenerateSignature(string ticket, string timestamp, string nonceStr, string url)
        {
            var stringToSign = $"jsapi_ticket={ticket}&noncestr={nonceStr}&timestamp={timestamp}&url={url}";
            
            using (var sha1 = SHA1.Create())
            {
                var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
                return BitConverter.ToString(hash).Replace("-", "").ToLower();
            }
        }

        /// <summary>
        /// 根据坐标获取地址信息（逆地理编码）
        /// </summary>
        /// <param name="latitude">纬度</param>
        /// <param name="longitude">经度</param>
        /// <returns>地址信息</returns>
        public static async Task<string> GetAddressByLocationAsync(double latitude, double longitude)
        {
            try
            {
                // 优先使用腾讯地图API
                var tencentAddress = await GetTencentAddressAsync(latitude, longitude);
                if (!string.IsNullOrEmpty(tencentAddress))
                {
                    return tencentAddress;
                }

                // 降级使用高德地图API
                var aMapAddress = await GetAMapAddressAsync(latitude, longitude);
                if (!string.IsNullOrEmpty(aMapAddress))
                {
                    return aMapAddress;
                }

                Console.WriteLine($"所有地图服务均无法获取地址信息，坐标: {latitude}, {longitude}");
                return "";
            }
            catch (Exception ex)
            {
                Console.WriteLine($"逆地理编码异常: {ex.Message}");
                return "";
            }
        }

        /// <summary>
        /// 使用腾讯地图API获取地址
        /// </summary>
        /// <param name="latitude">纬度</param>
        /// <param name="longitude">经度</param>
        /// <returns>地址信息</returns>
        private static async Task<string> GetTencentAddressAsync(double latitude, double longitude)
        {
            try
            {
                // 从配置获取腾讯地图API Key
                var apiKey = LFConfig.TencentMapKey; // 需要在配置中添加
                if (string.IsNullOrEmpty(apiKey))
                {
                    Console.WriteLine("腾讯地图API Key未配置");
                    return "";
                }

                var url = $"https://apis.map.qq.com/ws/geocoder/v1/?location={latitude},{longitude}&key={apiKey}&get_poi=1";
                
                using var httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(10);
                
                var response = await httpClient.GetStringAsync(url);
                Console.WriteLine($"腾讯地图API响应: {response}");
                
                var jsonDoc = System.Text.Json.JsonDocument.Parse(response);
                var root = jsonDoc.RootElement;
                
                if (root.TryGetProperty("status", out var status) && status.GetInt32() == 0)
                {
                    if (root.TryGetProperty("result", out var result))
                    {
                        var address = "";
                        
                        // 获取基础地址
                        if (result.TryGetProperty("address", out var addressElement))
                        {
                            address = addressElement.GetString() ?? "";
                        }
                        
                        // 获取POI信息
                        if (result.TryGetProperty("pois", out var pois) && pois.GetArrayLength() > 0)
                        {
                            var poi = pois[0];
                            if (poi.TryGetProperty("title", out var title))
                            {
                                var poiTitle = title.GetString();
                                if (!string.IsNullOrEmpty(poiTitle))
                                {
                                    address = $"{poiTitle}({address})";
                                }
                            }
                        }
                        
                        return address;
                    }
                }
                
                Console.WriteLine($"腾讯地图API返回状态异常: {status.GetInt32()}");
                return "";
            }
            catch (Exception ex)
            {
                Console.WriteLine($"腾讯地图API调用失败: {ex.Message}");
                return "";
            }
        }

        /// <summary>
        /// 使用高德地图API获取地址（备用）
        /// </summary>
        /// <param name="latitude">纬度</param>
        /// <param name="longitude">经度</param>
        /// <returns>地址信息</returns>
        private static async Task<string> GetAMapAddressAsync(double latitude, double longitude)
        {
            try
            {
                // 从配置获取高德地图API Key
                var apiKey = LFConfig.AMapKey; // 需要在配置中添加
                if (string.IsNullOrEmpty(apiKey))
                {
                    Console.WriteLine("高德地图API Key未配置");
                    return "";
                }

                var url = $"https://restapi.amap.com/v3/geocode/regeo?key={apiKey}&location={longitude},{latitude}&poitype=&radius=1000&extensions=all&batch=false&roadlevel=0";
                
                using var httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(10);
                
                var response = await httpClient.GetStringAsync(url);
                Console.WriteLine($"高德地图API响应: {response}");
                
                var jsonDoc = System.Text.Json.JsonDocument.Parse(response);
                var root = jsonDoc.RootElement;
                
                if (root.TryGetProperty("status", out var status) && status.GetString() == "1")
                {
                    if (root.TryGetProperty("regeocode", out var regeocode))
                    {
                        if (regeocode.TryGetProperty("formatted_address", out var formattedAddress))
                        {
                            return formattedAddress.GetString() ?? "";
                        }
                    }
                }
                
                Console.WriteLine($"高德地图API返回状态异常: {status.GetString()}");
                return "";
            }
            catch (Exception ex)
            {
                Console.WriteLine($"高德地图API调用失败: {ex.Message}");
                return "";
            }
        }

        /// <summary>
        /// 发送企业微信群消息
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="webhookKey">Webhook Key，如果为空则使用配置中的默认Key</param>
        /// <returns>发送结果</returns>
        public static async Task<bool> SendGroupMessageAsync(string message, string? webhookKey = null)
        {
            try
            {
                // 使用传入的webhookKey，如果为空则从数据库或配置中获取
                var key = webhookKey;
                if (string.IsNullOrEmpty(key))
                {
                    // 尝试从数据库参数配置获取
                    try
                    {
                        // 使用简化的方式直接创建ParamConfigManagerService实例
                        var paramConfigManager = new LF.Domain.Services.Iml.ParamConfigManagerService();
                        var config = paramConfigManager.GetByKey("webhook_key");
                        key = config?.Value;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"从数据库获取webhook_key失败: {ex.Message}");
                    }
                    
                    // 如果数据库中没有，再尝试配置文件
                    if (string.IsNullOrEmpty(key))
                    {
                        key = LFConfig.QyWeixin?.GroupWebhookKey;
                    }
                }
                
                if (string.IsNullOrEmpty(key))
                {
                    Console.WriteLine("企业微信群机器人Webhook Key未配置（请在系统参数配置中设置webhook_key）");
                    return false;
                }

                var webhookUrl = $"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={key}";
                
                var requestData = new
                {
                    msgtype = "text",
                    text = new
                    {
                        content = message
                    }
                };

                using var httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                
                var jsonContent = JsonSerializer.Serialize(requestData);
                var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
                
                Console.WriteLine($"企业微信群消息发送请求: {jsonContent}");
                
                var response = await httpClient.PostAsync(webhookUrl, content);
                var responseContent = await response.Content.ReadAsStringAsync();
                
                Console.WriteLine($"企业微信群消息发送响应: {responseContent}");
                
                if (response.IsSuccessStatusCode)
                {
                    var responseJson = JsonDocument.Parse(responseContent);
                    var errCode = responseJson.RootElement.GetProperty("errcode").GetInt32();
                    
                    if (errCode == 0)
                    {
                        Console.WriteLine("企业微信群消息发送成功");
                        return true;
                    }
                    else
                    {
                        var errMsg = responseJson.RootElement.GetProperty("errmsg").GetString();
                        Console.WriteLine($"企业微信群消息发送失败: {errCode} - {errMsg}");
                        return false;
                    }
                }
                else
                {
                    Console.WriteLine($"企业微信群消息发送HTTP请求失败: {response.StatusCode}");
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送企业微信群消息异常: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                return false;
            }
        }

        /// <summary>
        /// 发送企业微信群Markdown消息
        /// </summary>
        /// <param name="content">Markdown内容</param>
        /// <param name="webhookKey">Webhook Key，如果为空则使用配置中的默认Key</param>
        /// <returns>发送结果</returns>
        public static async Task<bool> SendGroupMarkdownMessageAsync(string content, string? webhookKey = null)
        {
            try
            {
                // 使用传入的webhookKey或配置中的默认Key
                var key = webhookKey ?? LFConfig.QyWeixin?.GroupWebhookKey;
                if (string.IsNullOrEmpty(key))
                {
                    Console.WriteLine("企业微信群机器人Webhook Key未配置");
                    return false;
                }

                var webhookUrl = $"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={key}";
                
                var requestData = new
                {
                    msgtype = "markdown",
                    markdown = new
                    {
                        content = content
                    }
                };

                using var httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                
                var jsonContent = JsonSerializer.Serialize(requestData);
                var content2 = new StringContent(jsonContent, Encoding.UTF8, "application/json");
                
                Console.WriteLine($"企业微信群Markdown消息发送请求: {jsonContent}");
                
                var response = await httpClient.PostAsync(webhookUrl, content2);
                var responseContent = await response.Content.ReadAsStringAsync();
                
                Console.WriteLine($"企业微信群Markdown消息发送响应: {responseContent}");
                
                if (response.IsSuccessStatusCode)
                {
                    var responseJson = JsonDocument.Parse(responseContent);
                    var errCode = responseJson.RootElement.GetProperty("errcode").GetInt32();
                    
                    if (errCode == 0)
                    {
                        Console.WriteLine("企业微信群Markdown消息发送成功");
                        return true;
                    }
                    else
                    {
                        var errMsg = responseJson.RootElement.GetProperty("errmsg").GetString();
                        Console.WriteLine($"企业微信群Markdown消息发送失败: {errCode} - {errMsg}");
                        return false;
                    }
                }
                else
                {
                    Console.WriteLine($"企业微信群Markdown消息发送HTTP请求失败: {response.StatusCode}");
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送企业微信群Markdown消息异常: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                return false;
            }
        }

        /// <summary>
        /// 发送工单相关的群消息
        /// </summary>
        /// <param name="workOrderNumber">工单号</param>
        /// <param name="customerName">客户名称</param>
        /// <param name="workOrderType">工单类型</param>
        /// <param name="operationType">操作类型（如：指派、完成、取消等）</param>
        /// <param name="operatorName">操作人姓名</param>
        /// <param name="additionalInfo">附加信息</param>
        /// <param name="webhookKey">Webhook Key，如果为空则使用配置中的默认Key</param>
        /// <returns>发送结果</returns>
        public static async Task<bool> SendWorkOrderGroupNotificationAsync(
            string workOrderNumber, 
            string customerName, 
            string workOrderType, 
            string operationType, 
            string operatorName, 
            string additionalInfo = "", 
            string? webhookKey = null)
        {
            try
            {
                var message = $"【工单{operationType}通知】\n" +
                             $"工单号：{workOrderNumber}\n" +
                             $"客户：{customerName}\n" +
                             $"类型：{workOrderType}\n" +
                             $"操作人：{operatorName}\n" +
                             $"时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}";

                if (!string.IsNullOrEmpty(additionalInfo))
                {
                    message += $"\n说明：{additionalInfo}";
                }

                return await SendGroupMessageAsync(message, webhookKey);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送工单群消息通知异常: {ex.Message}");
                return false;
            }
        }
    }


    public class PlanMsgEventData
    {
        public List<string> users { set; get; }
        public string title { set; get; }
        public string url { set; get; }
        public string description { set; get; }
    }
    /// <summary>
    /// 企业微信用户信息
    /// </summary>
    public class QyWeixinUserInfo
    {
        public string UserId { get; set; } = "";
        public string? DeviceId { get; set; }
        public string? OpenId { get; set; }
        public string? ExternalUserId { get; set; }
    }

    /// <summary>
    /// 企业微信用户详细信息
    /// </summary>
    public class QyWeixinUserDetail
    {
        public string UserId { get; set; } = "";
        public string Name { get; set; } = "";
        public string Mobile { get; set; } = "";
        public string Email { get; set; } = "";
        public string Avatar { get; set; } = "";
        public string Gender { get; set; } = "";
    }

    /// <summary>
    /// JSAPI签名配置信息
    /// </summary>
    public class JsApiSignatureConfig
    {
        public long Timestamp { get; set; }
        public string NonceStr { get; set; } = "";
        public string Signature { get; set; } = "";
        public string CorpId { get; set; } = "";
    }

    /// <summary>
    /// 逆地理编码结果
    /// </summary>
    public class ReverseGeocodeResult
    {
        public string Address { get; set; } = "";
        public double Latitude { get; set; }
        public double Longitude { get; set; }
    }
}
